home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jovept2.arc / WIND.C < prev   
Text File  |  1985-05-30  |  8KB  |  426 lines

  1. /* wind.c */
  2.  
  3. /* JOVE/MSDOS. K. Mitchum 1/85 */
  4. /* Modifications for personal use only. */
  5. /* original code J. Payne LSRHS 5/83 */
  6. /* Ken Mitchum */
  7. /* University of Pittsburgh */
  8. /* Decision Systems Laboratory */
  9.  
  10. /* This creates/deletes/divides/grows/shrinks windows.  */
  11.  
  12. #include "jove.h"
  13. #include "term.h"
  14. #include "screen.h"
  15.  
  16.  
  17. static char onlyone[] = "You only have one window, twit!";
  18. static char toosmall[] = "too small";
  19.  
  20.  
  21. /* First line in a window */
  22.  
  23. FLine(w)
  24. WINDOW    *w;
  25. {
  26.     WINDOW    *wp = fwind;
  27.     int    lineno = -1;
  28.  
  29.     do {
  30.         if (wp == w)
  31.             return lineno + 1;
  32.         lineno += wp->w_height;
  33.         wp = wp->w_next;
  34.     } while (wp != fwind);
  35.     complain("WINDOW?");
  36.     /* NOTREACHED */
  37. }
  38.  
  39. initwinds(b)
  40. BUFFER    *b;
  41. {
  42.     WINDOW    *wp = fwind;
  43.  
  44.     do {
  45.         if (wp->w_bufp == b) {
  46.             SetTop(wp, (wp->w_line = b->b_dot));
  47.             zero_wind(wp);
  48.         }
  49.         wp = wp->w_next;
  50.     } while (wp != fwind);
  51. }
  52.  
  53. /* Return last window on the screen */
  54.  
  55. WINDOW *
  56. lastwind()
  57. {
  58.     WINDOW *wp = fwind;
  59.  
  60.     do {
  61.         if (wp->w_next == fwind)
  62.             return wp;
  63.         wp = wp->w_next;
  64.     } while (wp != fwind);
  65.     /* NOTREACHED */
  66. }
  67.  
  68. WINDOW *
  69.  
  70. getwind()
  71. {
  72.     WINDOW    *wp;
  73.     
  74.     wp = (WINDOW *)emalloc(sizeof (WINDOW));
  75.     return wp;
  76. }
  77.  
  78. /* Delete `wp' from the screen.  If it is the only window left
  79.  * on the screen, then complain via error.  It gives its body
  80.  * to the next window if there is one, otherwise the previous
  81.  * window gets the body.  Resets link list and fwind if necessary.
  82.  */
  83.  
  84. del_wind(wp)
  85. WINDOW    *wp;
  86. {
  87.     WINDOW    *last = lastwind(),
  88.         *prev = wp->w_prev;
  89.  
  90.     if (wp->w_next == wp)
  91.         complain(onlyone);
  92.  
  93.     wp->w_prev->w_next = wp->w_next;
  94.     wp->w_next->w_prev = wp->w_prev;
  95.     
  96.     if (fwind == wp) {
  97.         fwind = wp->w_next;
  98.         fwind->w_height += wp->w_height;
  99.     } else if (wp == last)
  100.         last->w_prev->w_height += wp->w_height;
  101.     else
  102.         prev->w_height += wp->w_height;
  103.     if (curwind == wp)
  104.         SetWind(prev);
  105.     free((char *) wp);
  106. }
  107.  
  108. /* Divide the `wp'.  Complains if `wp' is too small to be split.
  109.  * It returns the new window
  110.  */
  111.  
  112. WINDOW *
  113. div_wind(wp)
  114. WINDOW    *wp;
  115. {
  116.     WINDOW    *new;
  117.  
  118.     if (wp->w_height < 4)
  119.         complain(toosmall);
  120.  
  121.     new = getwind();
  122.     new->w_offset = 0;
  123.     new->w_numlines = 0;
  124.     /* Reset the window bounds */
  125.     new->w_height = (wp->w_height / 2);
  126.     wp->w_height -= new->w_height;
  127.  
  128.     /* Set the lines such that w_line is the center in each window */
  129.     new->w_line = wp->w_line;
  130.     new->w_bufp = wp->w_bufp;
  131.     new->w_top = prev_line(new->w_line, HALF(new));
  132.  
  133.     /* Link the new window into the list */
  134.     new->w_prev = wp;
  135.     new->w_next = wp->w_next;
  136.     new->w_next->w_prev = new;
  137.     wp->w_next = new;
  138.     return new;
  139. }
  140.  
  141. /* Return one window previous to `wp'.  If at the first window
  142.  * on screen, then go to the last window
  143.  */
  144.  
  145. WINDOW *
  146. prev_wind(wp)
  147. WINDOW    *wp;
  148. {
  149.     return wp->w_prev;
  150. }
  151.  
  152. /* Next window from `wp' */
  153.  
  154. WINDOW *
  155. next_wind(wp)
  156. WINDOW    *wp;
  157. {
  158.     return wp->w_next;
  159. }
  160.  
  161. /* Initialze the first window setting the bounds to the size of the
  162.  * screen.  There is no buffer with this window.  See parse for the
  163.  * setting of this window.
  164.  */
  165.  
  166. winit()
  167. {
  168.     curwind = fwind = getwind();
  169.  
  170.     curwind->w_line = curwind->w_top = (LINE *) 0;
  171.     curwind->w_char = 0;
  172.     curwind->w_next = curwind->w_prev = fwind;
  173.     curwind->w_height = LI - 1;
  174. }
  175.  
  176. /* Change window into the previous window.  curwind becomes the new
  177.  * window
  178.  */
  179.  
  180. PrevWindow()
  181. {
  182.     WINDOW    *new = prev_wind(curwind);
  183.  
  184.     if (new == curwind)
  185.         complain(onlyone);
  186.     SetWind(new);
  187. }
  188.  
  189. /* Make new the current window */
  190.  
  191. SetWind(new)
  192. WINDOW    *new;
  193. {
  194.     if (new == curwind)
  195.         return;
  196.     curwind->w_line = curline;
  197.     curwind->w_char = curchar;
  198.     curwind->w_bufp = curbuf;
  199.     SetBuf(new->w_bufp);
  200.     if (!inlist(new->w_bufp->b_zero, new->w_line)) {
  201.         new->w_line = curline;
  202.         new->w_char = curchar;
  203.     }
  204.     DotTo(new->w_line, new->w_char);
  205.     if (curchar > strlen(linebuf))
  206.         new->w_char = curchar = strlen(linebuf);
  207.     curwind = new;
  208. }
  209.  
  210. /* Delete the current window if it isn't the only one left */
  211.  
  212. DelCurWindow()
  213. {
  214.     del_wind(curwind);
  215. }
  216.  
  217. /* Return the number of windows being displayed right now */
  218.  
  219. numwindows()
  220. {
  221.     WINDOW    *wp = fwind;
  222.     int    num = 0;
  223.  
  224.     do {
  225.         num++;
  226.         wp = wp->w_next;
  227.     } while (wp != fwind);
  228.     return num;
  229. }
  230.  
  231. WindFind()
  232. {
  233.     char    *fname = ask((char *) 0, FuncName());
  234.     BUFFER    *buf;
  235.  
  236.     if (buf = file_exists(fname))
  237.         pop_wind(buf->b_name, 0);
  238.     else {
  239.         if (numwindows() == 1)
  240.             curwind = div_wind(curwind);
  241.         else
  242.             curwind = next_wind(curwind);
  243.         SetBuf(do_find(curwind, fname));
  244.     }
  245. }
  246.  
  247. /* Go into one window mode by deleting all the other windows */
  248.  
  249. OneWindow()
  250. {
  251.     while (curwind->w_next != curwind)
  252.         del_wind(curwind->w_next);
  253. }
  254.  
  255. /* Look for a window containing a buffer whose name is `name' */
  256.  
  257. WINDOW *
  258. windlook(name)
  259. char    *name;
  260. {
  261.     BUFFER    *bp = (BUFFER *) buf_exists(name);
  262.     WINDOW    *wp = fwind;
  263.  
  264.     if (bp == 0)
  265.         return 0;
  266.     do {
  267.         if (wp->w_bufp == bp)
  268.             return wp;
  269.         wp = wp->w_next;
  270.     } while (wp != fwind);
  271.     return 0;
  272. }
  273.  
  274. /* Change window into the next window.  curwind becomes the new
  275.  * window
  276.  */
  277.  
  278. NextWindow()
  279. {
  280.     WINDOW    *new = next_wind(curwind);
  281.  
  282.     if (new == curwind)
  283.         complain(onlyone);
  284.     SetWind(new);
  285. }
  286.  
  287. /* Scroll the next window */
  288.  
  289. PageNWind()
  290. {
  291.     if (numwindows() == 1)
  292.         complain(onlyone);
  293.     NextWindow();
  294.     NextPage();
  295.     PrevWindow();
  296. }
  297.  
  298. /* Put a window with the buffer `name' in it.  Erase the buffer if
  299.  * `clobber' is non-zero.
  300.  */
  301.  
  302. pop_wind(name, clobber)
  303. char    *name;
  304. {
  305.     WINDOW    *wp;
  306.     BUFFER    *newb;
  307.  
  308.     if ((wp = windlook(name)) == 0) {
  309.         if (numwindows() == 1)
  310.             SplitWind();
  311.         else
  312.             PrevWindow();
  313.     } else
  314.         SetWind(wp);
  315.  
  316.     newb = do_select((WINDOW *) 0, name);
  317.     if (clobber)
  318.         initlist(newb);
  319.     tiewind(curwind, newb);
  320.     SetBuf(newb);
  321. }
  322.  
  323. GrowWindow()
  324. {
  325.     WindSize(curwind, abs(exp));
  326. }
  327.  
  328. ShrWindow()
  329. {
  330.     WindSize(curwind, -abs(exp));
  331. }
  332.  
  333. /* Change the size of the window by inc.  First arg is the window,
  334.  * second is the increment.
  335.  */
  336.  
  337. WindSize(w, inc)
  338. register WINDOW    *w;
  339. {
  340.     if (numwindows() == 1)
  341.         complain(onlyone);
  342.  
  343.     if (inc < 0) {    /* Shrinking this window */
  344.         if (w->w_height + inc < 2)
  345.             complain(toosmall);
  346.         w->w_height += inc;
  347.         w->w_prev->w_height -= inc;
  348.     } else
  349.         WindSize(w->w_next, -inc);
  350. }
  351.  
  352. /* Set the topline of the window, calculating its number in the buffer.
  353.  * This is for numbering the lines only.
  354.  */
  355.  
  356. SetTop(w, line)
  357. WINDOW    *w;
  358. register LINE    *line;
  359. {
  360.     register LINE    *lp = w->w_bufp->b_zero;
  361.     register int    num = 0;
  362.  
  363.     w->w_top = line;
  364.     if (w->w_numlines)
  365.         while (lp) {
  366.             num++;
  367.             if (line == lp)
  368.                 break;
  369.             lp = lp->l_next;
  370.         }
  371.     w->w_topnum = num;
  372. }
  373.  
  374. WNumLines()
  375. {
  376.     zero_wind(curwind);
  377.     /* So the redisplay will know to update the screen even if it
  378.      * looks like there are no differences.
  379.      */
  380.  
  381.     curwind->w_numlines = !curwind->w_numlines;
  382.     SetTop(curwind, curwind->w_top);
  383. }
  384.  
  385. zero_wind(wp)
  386. register WINDOW    *wp;
  387. {
  388.     register int    i,
  389.             upper;
  390.  
  391.     upper = FLine(wp);
  392.     for (i = 0; i < wp->w_height; i++)
  393.         oimage[upper + i].Line = (LINE *) -1;
  394. }
  395.  
  396. /* Return the line number that `line' occupies in `windes' */
  397.  
  398. in_window(windes, line)
  399. register WINDOW    *windes;
  400. register LINE    *line;
  401. {
  402.     register int    i;
  403.     LINE    *top = windes->w_top;
  404.  
  405.     for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
  406.         if (top == line)
  407.             return FLine(windes) + i;
  408.     return -1;
  409. }
  410.  
  411.  
  412.  
  413. /*--------------------------o.s. dependent------------------------*/
  414.  
  415. abs(i)
  416. int i;
  417. {
  418.     if(i >= 0) return i;
  419.     else return(-i);
  420. }
  421.  
  422.  
  423.  
  424.  
  425.  
  426.